import org.newdawn.slick.*;
import org.newdawn.slick.util.FontUtils;
import org.newdawn.slick.command.*;
import java.util.ArrayList;

/**
 * Handles keypresses. Uses keys set by the Control Map Menu.
 * 
 * @author Gerrit Jamerson, CodeMonkeys
 */
public class InputController implements InputProviderListener
{
    private InputProvider inputProvider;
    private ArrayList<Keys> keysDown;
    
    //Key commands
    private Command keyUp;
    private Command keyDown;
    private Command keyLeft;
    private Command keyRight;

    private Command keySelect;
    private Command keyBack;
    private Command keyAttack;
    private Command keyDefend;

    /**
     * Constructs the Input Controller
     */
    public InputController(GameContainer gameContainer)
    {                
        inputProvider = new InputProvider(gameContainer.getInput());
        inputProvider.addListener(this);

        keyUp = new BasicCommand("UP");
        keyDown = new BasicCommand("DOWN");
        keyLeft = new BasicCommand("LEFT");
        keyRight = new BasicCommand("RIGHT");
        keySelect = new BasicCommand("SELECT");
        keyBack = new BasicCommand("BACK");
        keyAttack = new BasicCommand("ATTACK");
        keyDefend = new BasicCommand("DEFEND");

        keysDown = new ArrayList<Keys>();
        setKeys();
    } //End constructor

    /**
     * Sets the key commands to their set key values from the settings.
     * Called once when constructed, then each time the key settings change.
     */
    public void setKeys()
    {
        inputProvider.bindCommand(new KeyControl(Settings.getKeyUp()), keyUp);
        inputProvider.bindCommand(new KeyControl(Settings.getKeyDown()), keyDown);
        inputProvider.bindCommand(new KeyControl(Settings.getKeyLeft()), keyLeft);
        inputProvider.bindCommand(new KeyControl(Settings.getKeyRight()), keyRight);

        inputProvider.bindCommand(new KeyControl(Settings.getKeySelect()), keySelect);
        inputProvider.bindCommand(new KeyControl(Settings.getKeyBack()), keyBack);
        inputProvider.bindCommand(new KeyControl(Settings.getKeyAttack()), keyAttack);
        inputProvider.bindCommand(new KeyControl(Settings.getKeyDefend()), keyDefend);
    } //End setKeys method

    /**
     * Overrided method from InputProviderListener interface
     */
    public void controlPressed(Command command)
    {
        Keys keyCommand = getKey(command);

        switch(GameController.getGameState())
        {
            case INGAME:
            GameController.getGameMode().keyPressed(keyCommand);
            break;
            
            case MAINMENU:
            MainMenuController.controlPressed(keyCommand);
            break;
        } //End switch
        
        keysDown.add(keyCommand);
        System.out.println("Pressed: " + command.toString());
    } //End controlPressed method

    /**
     * Overrided method from InputProviderListener interface
     */
    public void controlReleased(Command command)
    {
        Keys keyCommand = getKey(command);

        switch(GameController.getGameState())
        {
            case INGAME:
            GameController.getGameMode().keyReleased(keyCommand);
            break;
            
            case MAINMENU:
            MainMenuController.controlReleased(keyCommand);
            break;
        } //End switch
        
        keysDown.remove(keyCommand);
        System.out.println("Released: " + command.toString());
    } //End controlReleased method
    
    private Keys getKey(Command command)
    {
        Keys keyCommand = null;
        if(command.toString().contains("UP"))
        {
            keyCommand = Keys.UP;
        } //End if
        else if(command.toString().contains("DOWN"))
        {
            keyCommand = Keys.DOWN;
        } //End else if
        else if(command.toString().contains("LEFT"))
        {
            keyCommand = Keys.LEFT;
        } //End if
        else if(command.toString().contains("RIGHT"))
        {
            keyCommand = Keys.RIGHT;
        } //End else if
        else if(command.toString().contains("SELECT"))
        {
            keyCommand = Keys.SELECT;
        } //End else if
        else if(command.toString().contains("BACK"))
        {
            keyCommand = Keys.BACK;
        } //End else if
        else if(command.toString().contains("ATTACK"))
        {
            keyCommand = Keys.ATTACK;
        } //End else if
        else if(command.toString().contains("DEFEND"))
        {
            keyCommand = Keys.DEFEND;
        } //End else if
        
        return keyCommand;
    } //End getKey method
    
    /**
     * Returns whether the key is currently down or not.
     * 
     * @pre None
     * @param key The key to check.
     * @return True if the key is currently pressed.
     * @post None
     */
    public boolean isKeyDown(Keys key)
    {
        return keysDown.contains(key);
    } //End isKeyDown method
} //End class
